package org.file5.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.sf.jmimemagic.Magic;

import org.apache.log4j.Logger;
import org.file5.dao.DaoFascade;
import org.file5.domain.Article;
import org.file5.domain.BaseEntity.STATUS;
import org.file5.domain.Category;
import org.file5.domain.Entity2Entity;
import org.file5.domain.Entity2Entity.Relation;
import org.file5.domain.EntityComment;
import org.file5.domain.Person;
import org.file5.service.ArticleService;
import org.file5.util.DataBean;
import org.file5.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.googlecode.objectify.Key;

@Service("articleService")
public class ArticleServiceImpl implements ArticleService {

	private final Logger logger = Logger.getLogger(this.getClass());
	@Autowired
	DaoFascade df;
	private Magic jmimeMagicParser = new Magic();

	@Override
	public DataBean<Article> getArticles(int startPosition, int maxResult, Category category,STATUS status) {
		DataBean<Article> dataBean = df.getArticleDao().getArticlesBy(startPosition, maxResult, category,status);
		return dataBean;
	}


	@Override
	public boolean isArticleManager(Article article, String personUid) {
		if (article.getAuthorKey().getName().equals(personUid)) {
			return true;
		}
		return false;
	}

	@Override
	public Article setArticlePrimaryCategory(Article article, Category g) {
		article.setPrimaryCategoryKey(new Key<Category>(Category.class, g.getUid()));
		article = df.getBaseDao().addUpdate(article);
		article = df.getCategoryDao().addEntity2PrimaryCategoryTrail(Article.class, article,
				Relation.ARTICLE_IS_CATEGORY_MEMBER, g);
		return article;
	}

	@Override
	public Article setArticleGeneralPrimaryCategory(Article article, Category g) {
		article = df.getBaseDao().addUpdate(article);
		article = df.getCategoryDao().addEntity2PrimaryCategoryTrail(Article.class, article,
				Relation.ARTICLE_IS_CATEGORY_MEMBER, g);
		return article;
	}

	@Override
	public Article addArticle2Categories(String articleUid, String[] categoryUids) {
		Article article = df.getBaseDao().find(Article.class, articleUid);
		if (article != null && categoryUids != null && categoryUids.length > 0) {
			for (String pguid : categoryUids) {
				Category g = df.getBaseDao().find(Category.class, pguid);
				if (g != null) {
					Entity2Entity<Article, Category> p2g = new Entity2Entity<Article, Category>();
					p2g.setEntityKey(new Key<Article>(Article.class, article.getUid()));
					p2g.setRelation(Relation.ARTICLE_IS_CATEGORY_MEMBER);
					p2g.setEntity2Key(new Key<Category>(Category.class, pguid));
					df.getBaseDao().addUpdate(p2g);
				}
			}
		}
		return article;
	}

	@Override
	public Article delArticle2Categories(String articleUid, String[] categoryUids) {
		Article article = df.getBaseDao().find(Article.class, articleUid);
		if (article != null && categoryUids != null && categoryUids.length > 0) {
			for (String pguid : categoryUids) {
				Category g = df.getBaseDao().find(Category.class, pguid);
				if (g != null) {
					Entity2Entity<Article, Category> p2g = df.getBaseDao().findEntity2Entity(article,
							Relation.ARTICLE_IS_CATEGORY_MEMBER, g);
					if (p2g != null) {
						df.getBaseDao().remove(p2g);
					}
				}
			}
		}
		return article;
	}

	@Override
	public List<Category> getArticleCategories(Article article) {
		List<Category> result = new ArrayList<Category>(0);
		DataBean<Entity2Entity<Article, Category>> dataBean = df.getBaseDao().getEntity2EntitiesBy(0, 100, article,
				Relation.ARTICLE_IS_CATEGORY_MEMBER, (Category) null, null);
		if (dataBean != null) {
			for (Entity2Entity<Article, Category> e2e : dataBean.getData()) {
				result.add(df.getBaseDao().find(Category.class, e2e.getEntity2Key()));
			}
		}
		return result;
	}

	@Override
	public void delete(String uid) {
		Article article = df.getBaseDao().find(Article.class, uid);
		if (article != null) {
			DataBean<Entity2Entity<Article, Category>> dataBean = df.getBaseDao().getEntity2EntitiesBy(0, 100, article,
					Relation.ARTICLE_IS_CATEGORY_MEMBER, (Category) null, null);
			if (dataBean != null) {
				for (Entity2Entity<Article, Category> e2e : dataBean.getData()) {
					df.getBaseDao().remove(e2e);
				}
			}
			df.getBaseDao().remove(article);
		}

	}

	@Override
	public Article find(String uid, boolean withRelatedDetail) {
		Article article = null;
		if (uid != null && !uid.isEmpty()) {
			article = df.getBaseDao().find(Article.class, uid);
			if (article != null && withRelatedDetail) {
				article.setAuthor(df.getBaseDao().find(Person.class, article.getAuthorKey()));

				article.setPrimaryCategory(df.getBaseDao().find(Category.class, article.getPrimaryCategoryKey()));

			}
		}
		return article;
	}

	@Override
	public Article updateStatus(String uid, STATUS status) {
		Article article = df.getBaseDao().find(Article.class, uid);
		if (article != null) {
			DataBean<Entity2Entity<Article, Category>> edb = df.getBaseDao().getEntity2EntitiesBy(0, 1000, article,
					Entity2Entity.Relation.ARTICLE_IS_CATEGORY_MEMBER, null, null);
			if (edb != null && edb.getData() != null && !edb.getData().isEmpty()) {
				for (Entity2Entity<Article, Category> p2g : edb.getData()) {
					p2g.setStatus(status);
					df.getBaseDao().addUpdate(p2g);
				}
			}
			article.setStatus(status);
			article.setStatusUpdated(new Date());
			df.getBaseDao().addUpdate(article);
		}
		return article;
	}

	@Override
	public Article addArticle2Categories(Article article, List<Category> categories) {
		if (article != null && categories != null && !categories.isEmpty()) {
			for (Category g : categories) {
				Entity2Entity<Article, Category> p2g = new Entity2Entity<Article, Category>();
				p2g.setEntityKey(new Key<Article>(Article.class, article.getUid()));
				p2g.setRelation(Relation.ARTICLE_IS_CATEGORY_MEMBER);
				p2g.setEntity2Key(new Key<Category>(Category.class, g.getUid()));
				p2g.setStatus(article.getStatus());
				df.getBaseDao().addUpdate(p2g);
			}
		}
		return article;
	}

	@Override
	public DataBean<Article> getArticlesByProperties(int startPosition, int maxResult,final Object ...params) {
		return df.getBaseDao().getListByProperties(Article.class, startPosition, maxResult, params);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public EntityComment<Article> addComment(String articleUid, String parentCommentUid, String comment,
			String authorUid) {
		EntityComment<Article> eca = null;
		Article article = df.getBaseDao().find(Article.class, articleUid);
		Person author = df.getBaseDao().find(Person.class, authorUid);
		if (article != null && author != null) {
			eca = new EntityComment<Article>();
			eca.setUid(UUIDUtil.getRandomUUID());
			eca.setEntityKey(new Key<Article>(Article.class, articleUid));
			eca.setComment(comment);
			eca.setAuthorKey(new Key<Person>(Person.class, authorUid));
			eca.setStatus(STATUS.ONLINE);

			EntityComment pec = df.getBaseDao().find(EntityComment.class, parentCommentUid);
			if (pec != null) {
				eca.setParentCommentKey(new Key<EntityComment>(EntityComment.class, pec.getUid()));
			}
			
			eca = df.getBaseDao().addUpdate(eca);
			article.setCommentCount(article.getCommentCount() + 1);
			df.getBaseDao().addUpdate(article);
		}

		return eca;
	}

	@Override
	public DataBean<EntityComment> getArticleComments( int startPosition,
			int maxResult,String articleUid, String parentCommentUid) {
		Key<Article> ak = null;
		if (articleUid != null&&!articleUid.isEmpty()) {
			ak = new Key<Article>(Article.class, articleUid);
		}
		DataBean<EntityComment> db = df.getBaseDao().getListByProperties(EntityComment.class, startPosition, maxResult,
				EntityComment.FIELD_NAME_ENTITY_KEY, ak);
		if (db != null && db.getData() != null && !db.getData().isEmpty()) {
			for (EntityComment ec : db.getData()) {
				Person p = df.getBaseDao().find(ec.getAuthorKey());
				ec.setAuthor(p);
				Article ar = df.getBaseDao().find(ec.getEntityKey());
				ec.setEntity(ar);
			}
		}
		return db;
	}


	@Override
	public Article addUpdateReprintArticle(Article article, String authorBlogUrl, String authorEmail, String articleUid) {
		// TODO Auto-generated method stub
		return null;
	}
}
